package com.sky.aspect;

import com.sky.anno.AutoFill;
import com.sky.constant.AutoFillConstant;
import com.sky.context.BaseContext;
import com.sky.enumeration.OperationType;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;

import java.beans.beancontext.BeanContext;
import java.lang.reflect.Method;
import java.time.LocalDateTime;

/**
 * 自定义切面类，实现自动填充功能
 */
@Slf4j
@Aspect
@Component
public class AutoFillAspect {

    @Before("@annotation(com.sky.anno.AutoFill)")
    public void autoFill(JoinPoint joinPoint) throws Exception {
        log.info("开始进行数据填充");

        //1. 获取目标方法上的注解，并拿到操作类型
        MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature();
        Method method = methodSignature.getMethod();
        AutoFill autoFill = method.getAnnotation(AutoFill.class);
        OperationType operationType = autoFill.value();

        //2. 获取方法参数
        Object[] args = joinPoint.getArgs();
        if (args == null || args.length == 0) {
            return;
        }
        Object target = args[0]; // 实体对象

        LocalDateTime now = LocalDateTime.now();


        if (operationType == OperationType.INSERT) {
            // 填充创建时间和更新时间、创建人和更新人
            Method setCreateTime = target.getClass().getDeclaredMethod(AutoFillConstant.SET_CREATE_TIME, LocalDateTime.class);
            Method setUpdateTime = target.getClass().getDeclaredMethod(AutoFillConstant.SET_UPDATE_TIME, LocalDateTime.class);
            Method setCreateUser = target.getClass().getDeclaredMethod(AutoFillConstant.SET_CREATE_USER, Long.class);
            Method setUpdateUser = target.getClass().getDeclaredMethod(AutoFillConstant.SET_UPDATE_USER, Long.class);

            setCreateTime.invoke(target, now);
            setUpdateTime.invoke(target, now);
            setCreateUser.invoke(target, BaseContext.getCurrentId());
            setUpdateUser.invoke(target, BaseContext.getCurrentId());

        } else if (operationType == OperationType.UPDATE) {
            // 填充更新时间、更新人
            Method setUpdateTime = target.getClass().getDeclaredMethod("setUpdateTime", LocalDateTime.class);
            Method setUpdateUser = target.getClass().getDeclaredMethod("setUpdateUser", Long.class);

            setUpdateTime.invoke(target, now);
            setUpdateUser.invoke(target, BaseContext.getCurrentId());
        }
    }
}
